import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;

import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;


public class NewLessonForm extends IEWForms {

	/**
	 * Dialog form for add a new words in program.
	 */
	private static final long serialVersionUID = 1L;
	
	private ArrayList<EW_Vocabulary> newWordsList = new ArrayList<EW_Vocabulary>();
	private int curPos = 0;
		
	private JLabel jlbText;
	private JLabel jlbTranslation;
	private JLabel jlbNotification;
	
	private JTextField jtfText;
	private JTextField jtfTranslation;
	
	private JButton jbtNext;
	private JButton jbtCancel;
	private JButton jbtSave;
	
	private JPanel jpnAvailableActions;
	private JPanel jpnAvailableSettings;
	private JPanel jpnAlphabet;
	
	private JList jltAvalableTopic;
	private DefaultListModel model;
	private JScrollPane jspTopic;
	
	private ArrayList<EW_Topic> list;
	private JButton jbtAddNewTopic;
	private JLabel jlbAddNewTopic; 
	
	private EW_Topic selTopic = null;
	private EW_Vocabulary wordCard = null; 
	
	/**
	 * constructor 
	 * @param parent	main form which call that dialog 
	 */
	public NewLessonForm(JFrame parent){
		super(parent, "add new words to vocabulary");
		createFormComponents();
		doInitForm();
		this.setVisible(true);
	}
	
	/**
	 * Create new form and show word card. allow update word
	 * @param parent - main form
	 * @param word - word for changing
	 */
	public NewLessonForm(JFrame parent, EW_Vocabulary word){
		super(parent, "add new words to vocabulary");
		createFormComponents();
		doInitForm();
		fillWordCard(word);
		this.setVisible(true);
	}
	/**
	 * fill text fields by word data and allow update word;
	 * @param word
	 */
	private void fillWordCard(EW_Vocabulary word){
		jspTopic.setVisible(false);
		jltAvalableTopic.setVisible(false);
		jbtAddNewTopic.setVisible(false);
		jlbAddNewTopic.setVisible(false);
		jbtSave.setVisible(false);
		jbtNext.setText("Сохранить");
		jtfText.setText(word.getWord());
		jtfTranslation.setText(word.getInterpretation());
		wordCard = word;
	}
	
	private void createFormComponents(){
		jlbText = new JLabel();
		jlbTranslation = new JLabel();
		jlbNotification = new JLabel();
		
		jtfText = new JTextField();
		jtfTranslation = new JTextField();
		
		jbtNext = new JButton();
		jbtCancel = new JButton();
		jbtSave = new JButton();
		
		jbtAddNewTopic = new JButton();
		jlbAddNewTopic = new JLabel();
		
		jpnAvailableActions = new JPanel();
		jpnAvailableSettings = new JPanel(null);
		jpnAlphabet = new JPanel();	 
		model = new DefaultListModel();
		
		jltAvalableTopic = new JList(model);
		jltAvalableTopic.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		jspTopic = new JScrollPane(jltAvalableTopic, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		
		if (myParent.jcbTopic.getSelectedIndex() != 0){
			selTopic = new EW_Topic(myParent.jcbTopic.getSelectedItem().toString(), myParent.profile.getStudyLanguage());
		}
	}
	
	@Override
	/**
	 * prepare instance of new lesson form
	 * setup GUI
	 * add action logic.
	 */
	protected void doInitForm() {
		
		setLabelsName(); 
		doAddLettersLabel();
		
		this.setLayout(new BorderLayout());		
		int fWidth = myParent.getWidth();
		int large = fWidth - 10;
		int magic = 350; // count of pixel for good button
		
		jlbNotification.setBounds(5, 0, large, 25);
		jlbText.setBounds(5, 30, large, 25);
		jtfText.setBounds(5, 60, large, 25);
		jlbTranslation.setBounds(5, 90, large, 25);
		jtfTranslation.setBounds(5, 120, large, 25);
		jspTopic.setBounds(5, 150, large, 50);
		jlbAddNewTopic.setBounds(5, 205, large - 30, 25);
		jbtAddNewTopic.setBounds(large - 25, 205, 25, 25);
		jpnAvailableSettings.add(jlbNotification);
		jpnAvailableSettings.add(jlbText);
		jpnAvailableSettings.add(jtfText);
		jpnAvailableSettings.add(jlbTranslation);
		jpnAvailableSettings.add(jtfTranslation);
		jpnAvailableSettings.add(jlbAddNewTopic);
		jpnAvailableSettings.add(jbtAddNewTopic);
		
		jpnAvailableSettings.add(jspTopic);
		
		if (fWidth <= magic){
			jbtCancel.setPreferredSize(new Dimension((int)(fWidth * 0.30), 25));
			jbtNext.setPreferredSize(new Dimension((int)(fWidth * 0.30), 25));
			jbtSave.setPreferredSize(new Dimension((int)(fWidth * 0.30), 25));
			jpnAvailableActions.setLayout(new FlowLayout(FlowLayout.CENTER, (int)(fWidth * 0.025), 0));
		}
		jpnAvailableActions.add(jbtCancel);
		jpnAvailableActions.add(jbtNext);
		jpnAvailableActions.add(jbtSave);
		
		this.add(jpnAlphabet, BorderLayout.NORTH);
		this.add(jpnAvailableActions, BorderLayout.SOUTH);
		this.add(jpnAvailableSettings, BorderLayout.CENTER);
		
		setButtonListeners();
		if (selTopic != null)
			jltAvalableTopic.setSelectedValue(selTopic.getTopicName(), true);
	}

	/**
	 * procedure setup all needed actions for buttons and other components
	 */
	protected void setButtonListeners() {
		
		jbtCancel.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				doCloseForm();
			}
		});
		
		jbtNext.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (wordCard != null){
					doSetNewWordAndExit();
					return;
				}
				if (jtfText.getText().trim().equals("")){
					jtfText.requestFocusInWindow();
					jlbNotification.setText("Слово не может быть без букв");
					return;
				}
				EW_Vocabulary word = doSetNewWord();
				addTopicsToWord(word);
				newWordsList.add(word);
				changeCurentLatter();
				jlbNotification.setText("Введено новых слов " + Integer.toString(newWordsList.size()));
			}
		});
		
		jbtSave.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				saveNewLesson();
			}
		});
		
		jbtAddNewTopic.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				addTopicAndChangeList();
			}
		});
	}
	
	private EW_Vocabulary doSetNewWord(){
		String ferstLetter = jtfText.getText().toLowerCase().substring(0, 1);
		EW_Vocabulary word = new EW_Vocabulary(new EW_Alphabet(myParent.profile.getStudyLanguage(), ferstLetter));
		word.setWord(jtfText.getText());
		word.setInterpretation(jtfTranslation.getText());
		return word;
	}
	
	private void doSetNewWordAndExit(){
		EW_Vocabulary word = doSetNewWord();
		wordCard.setWord(word.getWord());
		wordCard.setInterpretation(word.getInterpretation());
		wordCard.updateCurrentRecord();
		doCloseForm();
	}
	
	private void addTopicAndChangeList(){
		new TopicForm(myParent);
		model.removeAllElements();
		fillTopicList();
	}
	
	private void addTopicsToWord(EW_Vocabulary word){
		int[] topics = jltAvalableTopic.getSelectedIndices();
		for (int i = 0; i < topics.length; i++) {
			EW_Topic topic = list.get(topics[i]);
			word.setTopicToWord(topic);
		}
		
	}
	
	/**
	 * change user form 
	 * 		change color for current and last label of letter
	 * 		change current position in alphabet (curPos)
	 * if it's last curPos in alphabet, changes will save in DB
	 * if current alphabet letter has mark "no word" it will be skip
	 */
	private void changeCurentLatter(){ 
		curPos++;
		jlbNotification.setText("");
		jtfTranslation.setText("");
		jtfText.setText("");
		jtfText.requestFocusInWindow();
		jltAvalableTopic.clearSelection();
		if (selTopic != null)
			jltAvalableTopic.setSelectedValue(selTopic.getTopicName(), true);
	}
	
	/**
	 * after entered all new words, this procedure will save them in DB
	 */
	private void saveNewLesson() {
		for (EW_Vocabulary word : newWordsList) {
			try	{
				if (word.insertCurrentRecord() != -1) {
					EW_Alphabet letter = word.getCurrentLetter();
					int count = letter.getWordsCount() + 1;
					letter.setWordsCount(count);
					letter.updateCurrentRecord();
				}
			}
			catch (Exception exept)	{
				exept.printStackTrace();
			}
		}
		doCloseForm();
	}
	
	private void doCloseForm(){
		myParent.changeTimerStatus();
		jbtCancel.removeActionListener(jbtCancel.getActionListeners()[0]);
		jbtNext.removeActionListener(jbtNext.getActionListeners()[0]);
		jbtSave.removeActionListener(jbtSave.getActionListeners()[0]);
		jbtAddNewTopic.removeActionListener(jbtAddNewTopic.getActionListeners()[0]);
		this.dispose();
	}

	/**
	 * when open, it's should add new labels with alhabet letter, and set colors
	 * 		RED - no words for letter
	 * 		GREEN - current letter for enter
	 * 		BLACK - all other letters
	 */
	private void doAddLettersLabel() {
		EW_Alphabet letters = new EW_Alphabet(myParent.profile.getStudyLanguage(), "");
		HashMap<String, String> select = new HashMap<String, String>();
		select.put("language", myParent.profile.getStudyLanguage());
		ArrayList<EW_Alphabet> lettersList = letters.getList(select);
		int pos = 0;
		for (EW_Alphabet alph : lettersList) {
			JLabel let = new JLabel(alph.getLetter());
			jpnAlphabet.add(let, pos);
			pos++;
		}
	}
	
	private void fillTopicList(){
		list = EW_Topic.getTopicList("<>", "''", myParent.profile.getStudyLanguage());
		for (int i = 0; i < list.size(); i++) {
			model.add(i, list.get(i).getTopicName());
		} 
	}
	@Override
	/*
	 * procedure for internationalization
	 */
	protected void setLabelsName() {
		this.setTitle(myParent.getTitle() + " - New Lesson");
		jlbText.setText("Слово или Фраза");
		jlbTranslation.setText("Перевод, ''варианты через ;''");
		jlbNotification.setForeground(Color.RED);
		
		jbtNext.setText("Следующая");
		jbtCancel.setText("Закрыть");
		jbtSave.setText("Сохранить");
		
		jlbAddNewTopic.setText("Добавить тему");
		jbtAddNewTopic.setIcon(new ImageIcon(this.getClass().getResource("resurse/add.gif")));
		fillTopicList();
	}
}
